package touchphysics.main.tools;



import touchphysics.main.gui.Renderer;
import touchphysics.main.gui.ToolBox;
import touchphysics.main.input.InputEvent;
import touchphysics.main.input.InputListener;
import touchphysics.main.shape.Circle;
import touchphysics.main.shape.Polygon;
import touchphysics.main.shape.Rectangle;
import touchphysics.main.shape.Shape;
import touchphysics.main.shape.ShapeStorage;
import touchphysics.math.Point;

/**
 * Tool das das zeichnen von speziellen Formen, wie
 * Polygon, Rechteck, Linie, Kreis handelt.
 * @author Oliver Schneider
 *
 */
public class SpecialDrawTool implements InputListener{

	/** Association zur ToolBox */
	private ToolBox toolBox;
	/** Association zum ShapeStorage */
	private ShapeStorage shapes;
	/** Association zum Renderer */
	private Renderer renderer;
	
	/** Die Form die gerade gezeichnet wird */
	private Shape cur;
	/** Der Startpunkt des Zeichnevorgangs. */
	private Point startPoint;
	
	/**
	 * Erstellt ein neues SpecialDrawTool.
	 * @param tb die ToolBox
	 * @param shapes Der ShapeStorage
	 * @param renderer der Renderer
	 */
	public SpecialDrawTool(ToolBox tb, ShapeStorage shapes, Renderer renderer) {
		this.toolBox=tb;
		this.shapes=shapes;
		this.renderer=renderer;
	}
	
	
	public void activated(InputEvent evt) {
		startPoint = evt.getPos();
		int selected = toolBox.getSelectedTool();
		
		switch(selected){
			case ToolBox.TOOL_RECTANGLE:
				cur = new Rectangle(startPoint.clone(),1,1,0);
				shapes.addShape(cur);
				break;
			case ToolBox.TOOL_CIRCLE:
				cur = new Circle(startPoint.clone(),1);
				shapes.addShape(cur);
				break;
			case ToolBox.TOOL_POLYGON:
				if(cur==null){
					cur = new Polygon(startPoint);
					((Polygon)cur).addPoint(startPoint.clone());
					shapes.addShape(cur);
				}else{
					Polygon curP = ((Polygon)cur);
					if(curP.isFirstPoint(startPoint, ShapeStorage.MAX_TOLERANZ)){
						curP.close();
						cur=null;
					}else{
						curP.addPoint(startPoint.clone());
					}
				}
				break;
			case ToolBox.TOOL_LINE:
				cur = new Polygon(startPoint);
				((Polygon)cur).addPoint((Point)startPoint.clone());
				shapes.addShape(cur);
				break;
			default:
				cur = null;
		}
		if(cur!=null){
			renderer.repaint();		
		}
	}

	public void dragged(InputEvent evt) {
		int selected = toolBox.getSelectedTool();
		Point delta = new Point((int)Math.abs(startPoint.x-evt.getPos().x),(int)Math.abs(startPoint.y-evt.getPos().y));
		Shape old = cur;
		switch(selected){
			case ToolBox.TOOL_RECTANGLE:
				Rectangle rect = (Rectangle)cur;
				Point midPoint = rect.getMidPoint();
				if(startPoint.x < evt.getPos().x){
					midPoint.x=startPoint.x+(delta.x/2f);
					rect.setWidth(delta.x);
				}else{
					midPoint.x=startPoint.x-delta.x/2f;
					rect.setWidth(-delta.x);
				}
				if(startPoint.y < evt.getPos().y){
					midPoint.y=startPoint.y+delta.y/2f;
					rect.setHeight(delta.y);
				}else{
					midPoint.y=startPoint.y-delta.y/2f;
					rect.setHeight(-delta.y);
				}
				break;
			case ToolBox.TOOL_CIRCLE:
				cur = new Circle(startPoint,(int)startPoint.distance(evt.getPos()));
				shapes.replace(old, cur);
				break;
			case ToolBox.TOOL_POLYGON:
				if(cur!=null){
					((Polygon)cur).getLastPoint().set(evt.getPos());
				}
				break;
			case ToolBox.TOOL_LINE:
				((Polygon)cur).getLastPoint().set(evt.getPos());
				break;
			
		}
		renderer.repaint();
	}

	public void deactivated(InputEvent evt) {
		if(toolBox.getSelectedTool()!=ToolBox.TOOL_POLYGON){
			cur = null;
		}else{
			if(cur instanceof Polygon){
				Polygon poly = (Polygon) cur;
				if(poly.getPoints().size()>3){
					if(poly.isFirstPoint(poly.getLastPoint(),ShapeStorage.MAX_TOLERANZ)){
						poly.getPoints().remove(poly.getPoints().size()-1);
						poly.close();
						cur=null;
					}
				}
				
				
			}
		}

		
	}




}
